package com.example.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.example.demo.common.Constants;
import com.example.demo.config.JsonUtil;
import com.example.demo.config.redis.RedisHandler;
import com.example.demo.entity.BaseResult;
import com.example.demo.entity.Person;
import com.example.demo.mapper.PersonMapper;
import com.example.demo.service.PersonService;
import com.example.demo.utils.IdGen;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author 张露晨
 * @date 2017/9/27 15:57.
 */
@Service
@Transactional
public class PersonServiceImpl extends ServiceImpl<PersonMapper, Person> implements PersonService {


    @Autowired
    private RedisHandler redisHandler;

    @Override
    public boolean addRedis(String name, String sex, Integer age) {
        String redisKey = Constants.REDISKEY;
        Person person = new Person(name, sex, age);
        person.setId(IdGen.uuid());
        boolean per = person.insert();
        boolean b = false;
        if (per) {
            //保存Map类型
            b = redisHandler.getLocalRedisTemplate().cacheHash(redisKey, "map", person.getId(), JsonUtil.toJson(person));

            //保存List类型
            List<String> list = new ArrayList<>();
            list.add(JsonUtil.toJson(person));
            b = redisHandler.getLocalRedisTemplate().cacheList(redisKey, "list", list);

            //保存String类型
            b = redisHandler.getLocalRedisTemplate().cacheStringValue(redisKey, "string", JsonUtil.toJson(person));

            Set<String> set = new HashSet<>();
            set.add(JsonUtil.toJson(person));
            //保存Set类型
            b = redisHandler.getLocalRedisTemplate().cacheSet(redisKey, "set", set);

            //保存ZSet
            b = redisHandler.getLocalRedisTemplate().cacheZSet(redisKey, "zset", JsonUtil.toJson(person));
        }
        return b;
    }

    @Override
    public boolean updateRedis(String id, String name, String sex, Integer age) {
        String redisKey = Constants.REDISKEY;
        boolean b = false;
        //修改数据库
        Person personSql = new Person().selectById(id);
        personSql.setName(name);
        personSql.setSex(sex);
        personSql.setAge(age);
        personSql.updateById();

        //获取Map类型
        Person personMap = JsonUtil.fromJson(redisHandler.getLocalRedisTemplate().getHash(redisKey, "map", id), Person.class);
        personMap.setName(name);
        personMap.setSex(sex);
        personMap.setAge(age);
        b = redisHandler.getLocalRedisTemplate().cacheHash(redisKey, "map", id, JsonUtil.toJson(personMap));

        //获取List类型
        List<String> entityList = redisHandler.getLocalRedisTemplate().getList(redisKey, "list");
        redisHandler.getLocalRedisTemplate().remove(redisKey, "list");
        List<String> list = new ArrayList<>();
        for (String entity : entityList) {
            Person person = JsonUtil.fromJson(String.valueOf(entity), Person.class);
            if (person.getId().equals(id)) {
                person.setName(name);
                person.setSex(sex);
                person.setAge(age);
            }
            list.add(JsonUtil.toJson(person));
        }
        b = redisHandler.getLocalRedisTemplate().cacheList(redisKey, "list", list);

        //获取String类型
        Person personStr = JsonUtil.fromJson(redisHandler.getLocalRedisTemplate().getStringValue(redisKey, "string"), Person.class);
        personStr.setName(name);
        personStr.setAge(age);
        personStr.setSex(sex);
        b = redisHandler.getLocalRedisTemplate().cacheStringValue(redisKey, "string", JsonUtil.toJson(personStr));

        //获取Set类型
        Set<String> entitySet = redisHandler.getLocalRedisTemplate().getSet(redisKey, "set");
        redisHandler.getLocalRedisTemplate().remove(redisKey, "set");
        for (String entity : entitySet) {
            Person person = JsonUtil.fromJson(String.valueOf(entity), Person.class);
            if (person.getId().equals(id)) {
                person.setName(name);
                person.setSex(sex);
                person.setAge(age);
            }
            redisHandler.getLocalRedisTemplate().cacheSet(redisKey, "set", JsonUtil.toJson(person));
        }

        //获取ZSet类型
        Set<String> zSet = redisHandler.getLocalRedisTemplate().getZSet(redisKey, "zset");
        redisHandler.getLocalRedisTemplate().remove(redisKey, "zset");
        for (String entity : zSet) {
            Person person = JsonUtil.fromJson(String.valueOf(entity), Person.class);
            if (person.getId().equals(id)) {
                person.setName(name);
                person.setSex(sex);
                person.setAge(age);
            }
            redisHandler.getLocalRedisTemplate().cacheZSet(redisKey, "zset", JsonUtil.toJson(person));
        }
        return b;
    }

    @Override
    public boolean deleteRedis(String id) {
        String redisKey = Constants.REDISKEY;
        boolean b = false;
        Person person = new Person().selectById(id);
        if (null != person) {
            person.deleteById();
        }
        //删除Map类型
        b = redisHandler.getLocalRedisTemplate().remove(redisKey, "map");

        //删除Map类型中的一个K,V
        b = redisHandler.getLocalRedisTemplate().removeHash(redisKey, "map", id);

        //删除String类型
        b = redisHandler.getLocalRedisTemplate().remove(redisKey, "string");

        /**
         * 练习删除redis集合类型时只删除其中的某个元素
         * 保持与数据库数据一致
         */

        //删除List类型
        b = redisHandler.getLocalRedisTemplate().remove(redisKey, "list");

        //删除Set类型
        b = redisHandler.getLocalRedisTemplate().remove(redisKey, "set");

        //删除ZSet类型
        b = redisHandler.getLocalRedisTemplate().remove(redisKey, "zset");
        return b;
    }

    @Override
    public Map<String, Person> findOneRedis(String id) {
        String redisKey = Constants.REDISKEY;
        Map<String, Person> map = new HashMap<>();
        //查询数据库
        Person personSql = new Person().selectById(id);
        if (null != personSql) {
            map.put("mySql", personSql);
        }
        //查询Map类型
        Person personMap = JsonUtil.fromJson(redisHandler.getLocalRedisTemplate().getHash(redisKey, "map", id), Person.class);
        map.put("map", personMap);

        //查询String类型
        Person personStr = JsonUtil.fromJson(redisHandler.getLocalRedisTemplate().getStringValue(redisKey, "string"), Person.class);
        map.put("string", personStr);

        //查询List类型
        List<String> list = redisHandler.getLocalRedisTemplate().getList(redisKey, "list");
        for (String entity : list) {
            Person person = JsonUtil.fromJson(entity, Person.class);
            if (person.getId().equals(id)) {
                map.put("list", person);
            }
        }

        //查询Set类型
        Set<String> set = redisHandler.getLocalRedisTemplate().getSet(redisKey, "set");
        for (String entity : set) {
            Person person = JsonUtil.fromJson(entity, Person.class);
            if (person.getId().equals(id)) {
                map.put("set", person);
            }
        }

        //查询ZSet类型
        Set<String> zSet = redisHandler.getLocalRedisTemplate().getZSet(redisKey, "zset");
        for (String entity : zSet) {
            Person person = JsonUtil.fromJson(entity, Person.class);
            if (person.getId().equals(id)) {
                map.put("zSet", person);
            }
        }
        return map;
    }

    @Override
    public BaseResult findAllRedis() {
        String redisKey = Constants.REDISKEY;
        Map<String, Object> resultMap = new HashMap<>();
        List<Person> personSql = new Person().selectAll();
        if (personSql.size() > 0) {
            resultMap.put("mySql", personSql);
        }
        //Map类型
        Map<Object, Object> map = redisHandler.getLocalRedisTemplate().getHashMap(redisKey,"map");
//        List<Person> personMap = new ArrayList<>();
//        for (Object obj : map.values()) {
//            Person person = JsonUtil.fromJson(String.valueOf(obj), Person.class);
//            personMap.add(person);
//        }
        resultMap.put("map", map.values());

        //String类型
        Person personStr = JsonUtil.fromJson(redisHandler.getLocalRedisTemplate().getStringValue(redisKey,"string"), Person.class);
        resultMap.put("string",personStr);

        //List类型
        List<String> list = redisHandler.getLocalRedisTemplate().getList(redisKey,"list");
        List<Person> personList = new ArrayList<>();
        for (String entity : list) {
            Person person = JsonUtil.fromJson(entity, Person.class);
            personList.add(person);
        }
        resultMap.put("list", personList);

        //Set类型
        Set<String> set = redisHandler.getLocalRedisTemplate().getSet(redisKey,"set");
        Set<Person> personSet = new HashSet<>();
        Person person = null;
        for(String entity : set) {
            person = JsonUtil.fromJson(entity, Person.class);
            personSet.add(person);
        }
        resultMap.put("set", personSet);

        //ZSet类型
        Set<String> zSet = redisHandler.getLocalRedisTemplate().getZSet(redisKey, "zset");
        Set<Person> personZSet = new HashSet<>();
        for (String entity : zSet) {
            Person personZ = JsonUtil.fromJson(entity, Person.class);
            personZSet.add(personZ);
        }
        resultMap.put("zSet", personZSet);

        return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, resultMap);
    }

}
